(function(global){
    ujs.define('date', 'ujs', {
        /**
         * 获取  Month Name.
         * @method getMonthName
         */
        getMonthName : function(date, isEntity) {
            if(isEntity === true){
                //使用entity表示字母，以避免冲突, 对应字母如下行注释代码。
                return ([
                    '&#74;&#97;&#110;','&#70;&#101;&#98;','&#77;&#97;&#114;',
                    '&#65;&#112;&#114;','&#77;&#97;&#121;','&#74;&#117;&#110;',
                    '&#74;&#117;&#108;','&#65;&#117;&#103;','&#83;&#101;&#112;',
                    '&#79;&#99;&#116;','&#78;&#111;&#118;','&#68;&#101;&#99;'
                ])[ date.getMonth() ];
            } else {
                return (['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'])[ date.getMonth() ];    
            }
        },
        /**
         * 获取 Week Name.
         * @method getWeekName
         */
        getWeekName : function(date, isEntity){  
            if(isEntity === true){          
                return ([
                    '&#83;&#117;&#110;', '&#77;&#111;&#110;', '&#84;&#117;&#101;', 
                    '&#87;&#101;&#100;', '&#84;&#104;&#117;&#114;', '&#70;&#114;&#105;', 
                    '&#83;&#97;&#116;'
                ])[ date.getDay() ];
            } else {
                return (['Sun', 'Mon', 'Tue', 'Wed', 'Thur', 'Fri', 'Sat'])[ date.getDay() ];
            }
        },
        /**
         * 日期格式化.如:
         * alert(new Date().format("yyyy-MM-dd"));
         * alert(new Date("january 12 2008 11:12:30").format("yyyy-MM-dd hh:mm:ss")); 
         * @method format
         */
        format : function(date, format){
            var o = {  
                /**
                 * 特殊的格式符，使用大写，如TZ, MN, WN。
                 * MM为月份小于10时，前补零，如:2012-01-11。
                 */
                'TZ' : parseInt( ujs.num.negetive(date.getTimezoneOffset()/60 )).toSignedNumberString('+'), //本地时间与 GMT 时间之间的时间差，以小时为单位.
                "q+" : Math.floor((date.getMonth() + 3) / 3), //quarter
                
                "y+" : date.getFullYear(),
                
                "MN" : this.getMonthName(date, true), //month name
                "M+" : date.getMonth() + 1, //month number
                
                "d+" : date.getDate(), //day
                
                "WN" : this.getWeekName(date),  //week
                
                "h+" : date.getHours(), //hour
                "H+" : (function(h){
                    return h < 13 ? h : h - 12;
                })(date.getHours()), //hour 12小时制
                "m+" : date.getMinutes(), //minute
                'MP' : date.getMinutes() - (Date.nowDateObj()).getMinutes(),    //minutes passed
                "s+" : date.getSeconds(), //second
                "DP" : (function(dataObj){  //AM/PM
                    return dataObj.getHours() < 12 ? 'AM' : 'PM';
                })(date)
            };
            for (var k in o) {
                if ( new RegExp( "(" + k + ")" ).test(format) ) {
                    var matchStr = RegExp.$1; 
                    format = format.replace(
                        matchStr, 
                        function(){
                            if(matchStr === 'yy'){
                                return o[k] % 100;
                            } else {
                                return ( matchStr.length > 1 && typeof(o[k]) == 'number' && o[k].inRegion(-1, 10) ) ? ('0' + o[k] ) : o[k];
                            }   
                        }                
                    );
                }
            }
            return format;
        },
        /**
         * 时间增量.
         * @method add
         */
        add : function(date, interval, number){ 
            switch( interval.toLowerCase() ){ 
                //年
                case "y" : 
                case "year" : 
                    return new Date( date.setFullYear( date.getFullYear() + number ) );
                //月 
                case "m" : 
                case "month" :
                    return new Date( date.setMonth( date.getMonth() + number ) );
                //天 
                case "d" :
                case "day" : 
                    return new Date( date.setDate( date.getDate() + number ) );
                //周 
                case "w" :
                case "week" : 
                    return new Date( date.setDate( date.getDate() + 7 * number ) );
                //小时 
                case "h" : 
                case "hour" :
                    return new Date( date.setHours( date.getHours() + number ) );
                //分钟 
                case "n" : 
                case "minute" :
                    return new Date( date.setMinutes( date.getMinutes() + number ) );
                //秒 
                case "s" :
                case "second" : 
                    return new Date( date.setSeconds( date.getSeconds() + number ) );
                //毫秒 
                case "l" :
                case "millisecond" : 
                    return new Date( date.setMilliseconds( date.getMilliseconds() + number ) ); 
            } 
        },        
        /**
         * 获取当前时间的时间段易读提示，如：
         * 1、< 60s, 显示为     “刚刚”
         * 2、>= 1min && < 60 min, 显示与当前时间差      “XX分钟前”
         * 3、>= 60min && < 1day, 显示与当前时间差       “今天 XX:XX”
         * 4、>= 1day && < 1year, 显示日期       “XX月XX日 XX:XX”
         * 5、>= 1year, 显示具体日期       “XXXX年XX月XX日 XX:XX”
         * @method getTimeTooltip
         * @return {String}
         */
        getTimeTooltip : function(date, formatsMap){
            var now = new Date();            
            if(!ujs.Type.isObject(formatsMap)){
                formatsMap = Date.timeTooltipFormat['cn'];
            }             
            if(date.getFullYear() < now.getFullYear()){
                // >= 1year.
                return this.format(date, formatsMap['five']);        
            } else {
                var pastH = (now - date)/3600000;     
                if(pastH > now.getHours()){
                    // >= 1day && < 1year            
                    return this.format(date, formatsMap['four']);
                } else if (pastH >= 1) {
                    // >= 60min && < 1day
                    return this.format(date, formatsMap['three']);
                } else {
                    var pastM = now.getMinutes() - date.getMinutes();
                    if( pastM > 1 ){
                        // >= 1min && < 60min                
                        return this.format(date, formatsMap['two']);
                    } else {
                        // < 60s.                
                        return this.format(date, formatsMap['one']);
                    }
                }
            } 
        },
        /**
         * Return the ISO day number for a date
         * @method getISODay
         */
        getISODay : function(date, isUtc) {
            // Native JS method - Sunday is 0, monday is 1 etc.
            var d = isUtc ? date.getUTCDay() : date.getDay();
            // Return d if not sunday; otherwise return 7
            return d ? d : 7;
        },   
        /**
         * Retuns true if year is a leap year; otherwise false
         * @method isLeapYear
         */
        isLeapYear : function(date, isUtc) {
            var y = isUtc ? date.getUTCFullYear() : date.getFullYear();
            return !(y % 4) && (y % 100) || !(y % 400);
        },
        /**
         * Return the number of days in the month
         * @method getDaysInMonth
         */
        getDaysInMonth : function(date, isUtc) {
            var m = isUtc ? date.getUTCMonth() : date.getMonth();
            // If feb.
            if (m == 1){
                return this.isLeapYear(date) ? 29 : 28;
            }
            // If Apr, Jun, Sep or Nov return 30; otherwise 31
            return (m == 3 || m == 5 || m == 8 || m == 10) ? 30 : 31;
        },          
        /**
         * 时间计时的初始时间.
         * Thu Jan 01 1970 08:00:00 GMT+0800 (China Standard Time)
         * 
         * @property originalStartDate
         * @type {Date}
         * @static
         * @default "new Date(0)"
         */
        originalStartDate : new Date(0),
        /**
         * 构建Date对象.
         * [Number milliseconds,]
         * [String dateString,]
         * [Object year, month, day,], [Object hour, minute, second, ms] 
         * @method from
         * @static
         */
        from : function(year /* milliseconds or dateString */, month, day, hour, minute, second, ms){
            if(arguments.length === 1){
                return new Date(year); 
            } else {
                return new Date( 
                    year, 
                    month === undefined ? null : month,   //若传入undefined，则new Date(...)返回Invalid Date。
                    day === undefined ? null : day, 
                    hour === undefined ? null : hour, 
                    minute === undefined ? null : minute, 
                    second === undefined ? null : second, 
                    ms === undefined ? null : ms 
                );
            }
        },    
        /**
         * 获取birthDate关联的年龄.
         * @return {Number}
         * @method getAge
         * @static
         */
        getAge : function(birthDate){
            if(ujs.Type.isString(birthDate)){
                birthDate = ujs.date.from(birthDate);
            }    
            var today = new Date(), 
                age = today.getFullYear() - birthDate.getFullYear(),
                m = today.getMonth() - birthDate.getMonth();
            if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
                age--;
            }
            return age; 
        },
        /**
         * 获取当前时间刻度.
         * @method tick
         * @static
         * @return {Number}
         */
        tick : function(){
            return (new Date()).getTime();
        },        
        /**
         * 获取当前时间对象.
         * @method nowDateObj
         * @static
         * @return {Date}
         */
        nowDateObj : function(){
            return new Date();
        },
        /**
         * 获取两个时间差.
         * @method dateDiff
         * @static
         */
        dateDiff : function( interval, date1, date2 ) { 
            if(!(date1 instanceof Date) ){
                date1 = ujs.date.from(date1);
            }
            if(!(date2 instanceof Date) ){
                
                date2 = ujs.date.from(date2);
            }
            var millisecondDiff = date2.getTime() - date1.getTime(); //相差毫秒数
            var monthDiff = ( date2.getFullYear() - date1.getFullYear() ) * 12 + ( date2.getMonth() - date1.getMonth() );
            switch( interval.toLowerCase() ) { 
                case "y" :
                case "year" :
                    return ( monthDiff / 12 ).toFixed(1);
                case "m" :
                case "month" :  
                    return monthDiff; 
                case "d" :
                case "day" : 
                    return parseInt( millisecondDiff/1000/60/60/24 ); 
                case "w" :
                case "week" : 
                    return parseInt( millisecondDiff/1000/60/60/24/7 ); 
                case "h" :
                case "hour" : 
                    return parseInt( millisecondDiff/1000/60/60 ); 
                case "n" :
                case "minute" : 
                    return parseInt( millisecondDiff/1000/60 );                 
                case "s" :
                case "second" : 
                    return parseInt( millisecondDiff/1000 );                 
                case "l" :
                case "millisecond" : 
                    return millisecondDiff; 
            } 
        },    
        /**
         * 解析字符串格式的时间，如：13-Nov-2013。 
         * //TODO 日期格式解析有待完善.
         * @method parseStrDate
         * @static
         * @return {Date}
         */
        parseStrDate : function(str){
            if(str){
                var parts = str.split('-');
                return new Date(
                    parseInt(parts[2]),
                    ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'].indexOf(parts[1]),
                    parseInt(parts[0])
                );
            }
        },        
        formatDate : function(time){
            var date = time ? new Date(time) : new Date(), 
                format = window.ujsConfig ? ujsConfig.dateFormat : "dd-MN-yyyy";    
            return date.format(format);
        },
        formatDateTime : function(time){
            var date = time ? new Date(time) : new Date(), 
                format = window.ujsConfig ? ujsConfig.dateTimeFormat : "dd-MN-yyyy hh:mm";    
            return date.format(format);
        },
        nowStr : function(){
            return (new Date()).toLocaleString();
        },
        /**
         * 预定义的几种时间段格式.
         */
        timeTooltipFormat : {
            'cn' : {
                'one' : '刚刚',
                'two' : 'MP分钟前',
                'three' : '今天 H:mm DP',
                'four' : 'M月dd日 H:mm DP',
                'five' : 'yy年MM月dd日 H:mm DP'    
            },
            'en' : {
                'one' : 'H:mm DP',
                'two' : 'H:mm DP',
                'three' : 'H:mm DP',
                'four' : 'H:mm DP M/dd',
                'five' : 'H:mm DP yy/MM/dd'    
            }
        }
    });
    
    ujs.alias(ujs.date, ujs.date.tick, 'now');

})(window);